/*
 * Created by Ben Kahn on 3/9/09
 */

package client.engine;

import java.awt.Component;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import server.BuddyList;
import server.Person;
import server.Preferences;
import server.Status;

import communication.BuddyPreferencesRequest;
import communication.BuddyStatusChangedRequest;
import communication.ConfirmFileTransferRequest;
import communication.ConfirmNewBuddyRequest;
import communication.ConversationOpenedRequest;
import communication.ErrorRequest;
import communication.FileAcceptedRequest;
import communication.FileSenderConnection;
import communication.ParticipantJoinedRequest;
import communication.ParticipantLeftRequest;
import communication.ReceiveMessageRequest;
import communication.Request;
import communication.ServerConnection;
import communication.SocketConnection;
import communication.StillOnlineRequest;

public class RequestConsumer extends Thread {

	private ServerConnection serverConnection;
	private boolean finished;
	private ChatEngine engine;
	private SocketConnection incomingConn;
	private final int incomingPort = 1234;
	
	public RequestConsumer(ChatEngine e)
	{
		try
		{
			serverConnection = new ServerConnection(incomingPort);
			finished = false;
			engine = e;
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
	}
	
	public void run()
	{
		while(!finished) {
		    SocketConnection incomingConn = null;
		    try{
		        incomingConn = serverConnection.accept();   // conn was created in [1], when initializing the thread.
		        
		        if(incomingConn != null){
			        // We read the request
			        Request req = incomingConn.readRequest();
			        handleRequest(req);
			        
			        // We have to determine the type of Request we just read:
			        

			    }
			    incomingConn.close(); // we close the connection to indicate we already received the message.
		    }catch(IOException e){
		        e.printStackTrace();
		    }
		    catch(ClassNotFoundException e) {
		    	e.printStackTrace();
		    }
		   
		    

		}
	}
	
	public void handleRequest(Request r)
	{
		if(r == null)
		{
			System.err.println("Null request received: " + r);
		}
		else if(r instanceof BuddyPreferencesRequest)
		{
			BuddyPreferencesRequest req = (BuddyPreferencesRequest)r;
			handleBuddyPreferencesRequest(req);
		}
		else if(r instanceof ReceiveMessageRequest)
		{
			ReceiveMessageRequest req = (ReceiveMessageRequest)r;
			handleReceiveMessageRequest(req);
		}
		else if(r instanceof ErrorRequest)
		{
			ErrorRequest req = (ErrorRequest)r;
			handleErrorRequest(req);
		}
		else if(r instanceof ConversationOpenedRequest)
		{
			ConversationOpenedRequest req = (ConversationOpenedRequest)r;
			handleConversationOpenedRequest(req);
		}
		else if(r instanceof ParticipantJoinedRequest)
		{
			ParticipantJoinedRequest req = (ParticipantJoinedRequest)r;
			handleParticipantJoinedRequest(req);
		}
		else if(r instanceof ParticipantLeftRequest)
		{
			ParticipantLeftRequest req = (ParticipantLeftRequest)r;
			handleParticipantLeftRequest(req);
		}
		else if(r instanceof BuddyStatusChangedRequest)
		{
			BuddyStatusChangedRequest req = (BuddyStatusChangedRequest)r;
			handleBuddyStatusChangedRequest(req);
		}
		else if(r instanceof ConfirmNewBuddyRequest)
		{
			ConfirmNewBuddyRequest req = (ConfirmNewBuddyRequest)r;
			handleConfirmNewBuddyRequest(req);
		}else if(r instanceof ConfirmFileTransferRequest){
			ConfirmFileTransferRequest req = (ConfirmFileTransferRequest) r;
			handleConfirmFileTransferRequest(req);
		}else if(r instanceof FileAcceptedRequest){
			FileAcceptedRequest req = (FileAcceptedRequest) r;
			handleFileAcceptedRequest(req);
		}
		else if(r instanceof StillOnlineRequest){
			//Do Nothing
		}
		else
		{
			System.err.println("Request of unknown type received: " + r);
		}
	}
	
	private void handleConfirmFileTransferRequest(ConfirmFileTransferRequest req) {
		
		String sender = req.getSender();
		String receiver = req.getReceiver();
		String path = req.getfilePath();
		String file = req.getFileName();
		InetAddress ip = req.getIP();
		int port = req.getPort();
		
		engine.handleConfirmFileTransfer(sender, receiver, path, file, ip, port);
		
	}

	public void handleBuddyPreferencesRequest(BuddyPreferencesRequest r)
	{
		BuddyList bl = r.getBuddyList();
		Preferences pref = r.getPreferences();
		Person owner = r.getOwner();
		
		if(owner != null){
			engine.setUsername(r.getOwner().getUsername());
		}
		
		if(pref != null){ 
			engine.setPreferences(r.getPreferences());
		}
		
		engine.setBuddyList(bl);
	}
	
	public void handleReceiveMessageRequest(ReceiveMessageRequest r)
	{
		engine.receiveMessage(r.getConversationID(), r.getSender(), r.getMessage());
	}
	
	public void handleErrorRequest(ErrorRequest r)
	{
		engine.errorFromServer(r.getErrorMessage());
	}
	
	public void handleConversationOpenedRequest(ConversationOpenedRequest r)
	{
		ArrayList<String> buddies = r.getBuddies();
		String id = r.getConvID();
		
		engine.conversationOpened(buddies, id);
	}
	
	public void handleParticipantJoinedRequest(ParticipantJoinedRequest r)
	{
		String buddy = r.getBuddy();
		String id = r.getConvID();
		
		engine.addParticipantToConversation(buddy, id);
	}
	
	public void handleParticipantLeftRequest(ParticipantLeftRequest r)
	{
		String buddy = r.getBuddy();
		String id = r.getConvID();
		
		engine.removeParticipantFromConversation(buddy, id);
	}
	
	public void handleBuddyStatusChangedRequest(BuddyStatusChangedRequest r)
	{
		String buddy = r.getBuddy();
		Status newStatus = r.getStatus();
		engine.handleBuddyStatusChange(buddy, newStatus);
	}
	
	public void handleConfirmNewBuddyRequest(ConfirmNewBuddyRequest r)
	{
		String buddy = r.getSender();
		engine.handleConfirmNewBuddy(buddy);
	}
	
	public void handleFileAcceptedRequest(FileAcceptedRequest r){
		
		final String filename = r.getfilePath();
		final InetAddress IP = r.getIP();
		final int port = r.getPort();
		
		System.out.println("The file " + filename + " was accepted.");
		
		Runnable send = new Runnable(){

			@Override
			public void run() {
				try{
					System.out.println("I'm the thread which is sending.");
					FileSenderConnection sender = new FileSenderConnection(IP, port);
					sender.sendFile(filename);
					System.out.println("File sent");
					JOptionPane.showMessageDialog(null, "File sent", "File Confirmation", 1);
				}catch(Exception e){
					
				}
			}
			
		};
		
		Thread sendThread = new Thread(send);
		sendThread.start();
	}	
	
	public void setFinished(boolean f)
	{
		finished = f;
	}
	//TODO: Add methods for handling each individual request type
}
